/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.coreGenerator.base.entitygen;

import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.field.FieldGenerator;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.api.attr.ChildEntityAttribute;
import com.inspur.edp.cef.api.dataType.entity.ICefEntity;
import com.inspur.edp.cef.core.datatype.CefEntity;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.gencommon.ReflectionUtils;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.createdtmassmethod.EntityCreateAfterCreateDtmAssMethodGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.createdtmassmethod.EntityCreateAfterModifyDtmAssMethodGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.createdtmassmethod.EntityCreateBeforeSaveDtmAssMethodGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.createvalassmethod.EntityCreateAfterModifyValAssMethodGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.createvalassmethod.EntityCreateBeforeSaveValAssMethodGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.field.ResourceInfoFieldGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.method.EntityCtorGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.method.GetResInfoGenerator;
import com.inspur.edp.cef.generator.coreGenerator.base.entitygen.method.GetResInfoInstanceGenerator;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import java.util.ArrayList;
import java.util.HashMap;

public abstract class EntityImplGenerator extends DataTypeImpGenerator {

  protected HashMap<String, ChildEntityAttribute> childEntitiesAttribute = new HashMap<>();
  protected HashMap<String, String> ChildEntitys = new HashMap<>();

  protected EntityImplGenerator(EntityGeneratorContext parContext, IGspCommonObject node) {
    super(parContext, node);
//    SetChildEntityTypeInfoToMgrType();
  }

  protected boolean getIsRoot() {
    return true;
  }

  public EntityImplGenContext getEntityImplGenContext()
  {return (EntityImplGenContext) super.getDataTypeImplContext();}


  @Override
  protected final void addExtendParentInterfaces(ArrayList<TypeInfo> parents) {
    parents.add(new TypeInfo(ICefEntity.class.getTypeName()));
    addExtendEntityParentInterfaces(parents);
  }

  protected void addExtendEntityParentInterfaces(ArrayList<TypeInfo> parents) {

  }

//  //TODO: VO集成cef后可以去掉
//  private void SetChildEntityTypeInfoToMgrType() {
//    ChildEntityAttribute[] attrs = (ChildEntityAttribute[]) ReflectionUtils
//        .getAnnotations(entityTypeInfo.getActionImplType(), ChildEntityAttribute.class);
//    if (attrs == null || attrs.length == 0) {
//      return;
//    }
//    for (ChildEntityAttribute item : attrs) {
//      CefEntityTypeInfo tempVar = new CefEntityTypeInfo();
//      tempVar.setActionImplType(item.entityActionImplType());
//      tempVar.setAllInterfaceType(item.entityAllType());
//      tempVar.setActionInterfaceType(item.entityActionType());
//      CefEntityTypeInfo cefTypeInfo = tempVar;
//
//      setEntityTypeInfoToMgrType(ParentContext, item.nodeCode(), cefTypeInfo);
//    }
//  }

  @Override
  protected DataTypeImpContext getDataTypeImpContext() {
    DataTypeImpContext context = new EntityImplGenContext();
    ParentContext.setMainDataTypeContext(context);
    return context;
  }

  @Override
  protected ClassMethodGenerator getConstructorGenerator(String typeName, String dataName) {
    return new EntityCtorGenerator(typeName, dataName);
  }

  @Override
  protected ArrayList<BaseGenerator> createClassExtendChildGenrators() {
    ArrayList<BaseGenerator> baseExtendGens = super.createClassExtendChildGenrators();
    if (baseExtendGens == null) {
      baseExtendGens = new ArrayList<BaseGenerator>();
    }

    addChildEntitiesGenerators(baseExtendGens);

    if (getIsRoot()) {
      MediateType baseDataType = ParentContext.getProjContext().getCefGenContext()
          .getDataInterfaceTypes().get(dataType.getCode());
      addAccessorGenerators(baseExtendGens, ParentContext, dataType.getCode(), baseDataType);
    }

    baseExtendGens.add(new GetResInfoGenerator(resInfoName, dataType, ParentContext));
    baseExtendGens.add(new GetResInfoInstanceGenerator(dataType));

    return baseExtendGens;
  }

  @Override
  protected ArrayList<FieldGenerator> createFieldGenerator() {
    ArrayList<FieldGenerator> fieldGenerators = super.createFieldGenerator();
    if (fieldGenerators == null) {
      fieldGenerators = new ArrayList<>();
    }

    fieldGenerators.add(new ResourceInfoFieldGenerator(resInfoName, ParentContext));

    return fieldGenerators;
  }

  private final static String resInfoName = "entityResInfo";

  private void addChildEntitiesGenerators(ArrayList<BaseGenerator> list) {
    for (IGspCommonObject item : ((IGspCommonObject)dataType).getContainChildObjects()) {

      EntityImplGenerator childGen = getChildEntityImplGenerator(item);
      list.add(childGen);
      this.ChildEntitys.put(item.getCode(), childGen.getName());
    }
  }

  protected abstract EntityImplGenerator getChildEntityImplGenerator(IGspCommonObject node);

  protected void addAccessorGenerators(ArrayList<BaseGenerator> gens,
      EntityGeneratorContext entityContext, String nodeCode, MediateType baseDataType) {
  }

  @Override
  public boolean getGenData() {
    return getIsRoot();
  }

  @Override
  protected void afterGenerate() {
    super.afterGenerate();
    //ParentContext.getProjContext().setMainDataType(new MediateType(getName(), ""));
  }

//  @Override
//  protected ClassMethodGenerator getCreateAfterModifyDtmAssMethodGenerator() {
//    return new EntityCreateAfterModifyDtmAssMethodGenerator(ParentContext, nodeCode);
//  }
//
//  @Override
//  protected ClassMethodGenerator getCreateAfterCreateDtmAssMethodGenerator() {
//    return new EntityCreateAfterCreateDtmAssMethodGenerator(ParentContext, nodeCode);
//  }
//
//  @Override
//  protected ClassMethodGenerator getCreateBeforeSaveDtmAssMethodGenerator() {
//    return new EntityCreateBeforeSaveDtmAssMethodGenerator(ParentContext, nodeCode);
//  }
//
//  @Override
//  protected ClassMethodGenerator getCreateAfterModifyValAssMethodGenerator() {
//    return new EntityCreateAfterModifyValAssMethodGenerator(ParentContext, nodeCode);
//  }
//
//  @Override
//  protected ClassMethodGenerator getCreateBeforeSaveValAssMethodGenerator() {
//    return new EntityCreateBeforeSaveValAssMethodGenerator(ParentContext, nodeCode);
//  }
}
